package com.org.forex;

import java.util.Calendar;
import java.util.Date;

public class Price implements java.io.Serializable {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private float value_open;
	private float value_high;
	private float value_low;
	private float value_close;
	private Date date;
	private float volume;

	@Override
	public String toString() {
		return "Price [value_open=" + value_open + ", value_high=" + value_high
				+ ", value_low=" + value_low + ", value_close=" + value_close
				+ ", date=" + date + ", volume=" + volume + "]";
	}

	public float getValue_open() {
		return value_open;
	}

	public void setValue_open(float value_open) {
		this.value_open = value_open;
	}

	public float getValue_high() {
		return value_high;
	}

	public void setValue_high(float value_high) {
		this.value_high = value_high;
	}

	public float getValue_low() {
		return value_low;
	}

	public void setValue_low(float value_low) {
		this.value_low = value_low;
	}

	public float getValue_close() {
		return value_close;
	}

	public void setValue_close(float value_close) {
		this.value_close = value_close;
	}

	public Date getDate() {
		return date;
	}

	public void setDate(Date date) {
		this.date = date;
	}

	public float getVolume() {
		return volume;
	}

	public void setVolume(float volume) {
		this.volume = volume;
	}

	public Price(float value_open, float value_high, float value_low,
			float value_close, Date date, float volume) {
		super();
		this.value_open = value_open;
		this.value_high = value_high;
		this.value_low = value_low;
		this.value_close = value_close;
		this.date = date;
		this.volume = volume;
	}

	public static double diffClose(Price[] p1, int p1_index, Price[] p2,
			int p2_index, int size) {
		double result = 0;
		float[] d = new float[size];
		float sum = 0;
		for (int i = 0; i < size; i++) {
			d[i] = p1[i + p1_index].getValue_close()
					- p2[i + p2_index].getValue_close();
			sum += d[i];
		}
		float mean = sum / (float) size;
		sum = 0;
		for (int i = 0; i < size; i++) {
			d[i] = d[i] - mean;
			sum += d[i] * d[i];
		}
		sum = sum / (float) size;
		result = Math.sqrt(sum);
		return result;
	}

	public static double diffOpen(Price[] p1, int p1_index, Price[] p2,
			int p2_index, int size) {
		double result = 0;
		float[] d = new float[size];
		float sum = 0;
		for (int i = 0; i < size; i++) {
			d[i] = p1[i + p1_index].getValue_open()
					- p2[i + p2_index].getValue_open();
			sum += d[i];
		}
		float mean = sum / (float) size;
		sum = 0;
		for (int i = 0; i < size; i++) {
			d[i] = d[i] - mean;
			sum += d[i] * d[i];
		}
		sum = sum / (float) size;
		result = Math.sqrt(sum);
		return result;
	}

	public static double diffHigh(Price[] p1, int p1_index, Price[] p2,
			int p2_index, int size) {
		double result = 0;
		float[] d = new float[size];
		float sum = 0;
		for (int i = 0; i < size; i++) {
			d[i] = p1[i + p1_index].getValue_high()
					- p2[i + p2_index].getValue_high();
			sum += d[i];
		}
		float mean = sum / (float) size;
		sum = 0;
		for (int i = 0; i < size; i++) {
			d[i] = d[i] - mean;
			sum += d[i] * d[i];
		}
		sum = sum / (float) size;
		result = Math.sqrt(sum);
		return result;
	}

	public static double diffLow(Price[] p1, int p1_index, Price[] p2,
			int p2_index, int size) {
		double result = 0;
		float[] d = new float[size];
		float sum = 0;
		for (int i = 0; i < size; i++) {
			d[i] = p1[i + p1_index].getValue_low()
					- p2[i + p2_index].getValue_low();
			sum += d[i];
		}
		float mean = sum / (float) size;
		sum = 0;
		for (int i = 0; i < size; i++) {
			d[i] = d[i] - mean;
			sum += d[i] * d[i];
		}
		sum = sum / (float) size;
		result = Math.sqrt(sum);
		return result;
	}

	public static double diffCandle(Price[] p1, int p1_index, Price[] p2,
			int p2_index, int size) {
		double result = 0;
		float[] d = new float[size];
		float sum = 0;
		for (int i = 0; i < size; i++) {
			d[i] = (p1[i + p1_index].getValue_low()
					+ p1[i + p1_index].getValue_close() + p1[i + p1_index]
					.getValue_high())
					- (p2[i + p2_index].getValue_close()
							+ p2[i + p2_index].getValue_high() + p2[i
							+ p2_index].getValue_low());
			sum += d[i];
		}
		float mean = sum / (float) size;
		sum = 0;
		for (int i = 0; i < size; i++) {
			d[i] = Math.abs(d[i] - mean);
			sum += d[i] * d[i];
		}
		sum = sum / (float) size;
		result = Math.sqrt(sum);
		return result;
	}

	public static boolean checkContinuous(Price[] prices, int start_index,
			int end_index) {
		for (int i = start_index; i < end_index - 1; i++) {
			Date startDate = prices[i].getDate();
			Date endDate = prices[i + 1].getDate();
			long startTime = startDate.getTime();
			long endTime = endDate.getTime();
			long diffTime = endTime - startTime;
			long diffDays = diffTime / (1000 * 60 * 60 * 24);
			if (diffDays >= 1)
				return false;

		}
		return true;
	}

	public static int[] getAllDiff(Price[] prices, Price[] compare_prices,
			int start_index, int size, boolean iscontinuos, int start_year,
			int end_year, int diff) {
		int[] index = new int[10];
		double[] value = new double[10];
		for (int j = 0; j < 10; j++) {
			value[j] = 1000;
		}
		for (int i = 0; i < prices.length - size; i++) {
			// check continuous
			if (iscontinuos)
				if (!checkContinuous(prices, i, i + size))
					continue;
			// check diff
			Calendar cal = Calendar.getInstance();
			cal.setTime(prices[i].getDate());

			long diff_time = Math.abs(prices[i].getDate().getTime()
					- compare_prices[start_index].getDate().getTime());
			long diffDays = diff_time / (24 * 60 * 60 * 1000);
			if (diffDays < diff)
				continue;

			int year = cal.get(Calendar.YEAR);
			if (!(year <= end_year && year >= start_year))
				continue;
			double dif = Price.diffClose(prices, i, compare_prices,
					start_index, size)
					+ Price.diffOpen(prices, i, compare_prices, start_index,
							size);
			// + Price.diffHigh(prices, i, compare_prices, start_index,
			// size)
			// + Price.diffLow(prices, i, compare_prices, start_index,
			// size);
			for (int j = 0; j < 10; j++) {
				if (dif <= value[j]) {
					value[j] = dif;
					index[j] = i;
					break;
				}
			}
		}
		// System.out.println("do lech nho nhat :" + value[0]);
		// System.out.println("index nho nhat :" + index[0]);
		return index;
	}

	public static int[] getAllDiff1(Price[] prices, Price[] compare_prices,
			int start_index, int size, boolean iscontinuos) {
		int[] index = new int[10];
		double[] value = new double[10];
		for (int j = 0; j < 10; j++) {
			value[j] = 1000;
		}
		for (int i = 0; i < prices.length - size; i++) {
			if (iscontinuos)
				if (!checkContinuous(prices, i, i + size))
					continue;
			// chek time stamp
			if (compare_prices[start_index].getDate().getTime()
					- prices[i].getDate().getTime() < (1000 * 60 * 60 * 24) * 10)
				continue;
			double dif = Price.diffCandle(prices, i, compare_prices,
					start_index, size);
			for (int j = 0; j < 10; j++) {
				if (dif <= value[j]) {
					value[j] = dif;
					index[j] = i;
					break;
				}
			}
		}
		// System.out.println("do lech nho nhat :" + value[0]);
		// System.out.println("index nho nhat :" + index[0]);
		return index;
	}
}
